home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / magazi~1 / 278 / vditext.10 < prev    next >
Text File  |  1986-11-01  |  15KB  |  307 lines

  1.       Permission to reprint or excerpt is granted only if the following
  2.       line appears at the top of the article:
  3.  
  4.       ANTIC PUBLISHING INC., COPYRIGHT 1986.  REPRINTED BY PERMISSION.
  5.  
  6.  
  7.  
  8.       PROFESSIONAL GEM  by Tim Oren
  9.       Column #10 - VDI Graphics: Text Output
  10.  
  11.  
  12.            This  issue of ST PRO GEM concludes the two column series  on
  13.       VDI  with a look at simple VDI  text output,  and ways to optimize
  14.       its  speed.   There is also a Feedback section.   You may find the
  15.       associated  download  file under the name GMCL10.C in DL3  of  the
  16.       ATARI16 SIG (PCS-58).
  17.  
  18.            To  keep  the size of this first discussion  of  text  within
  19.       reason, I am going to restrict it to use of the mono-spaced system
  20.       font   in  its  default  size  and  orientation.    Discussion  of
  21.       alternate and proportionally spaced fonts,  baseline rotation, and
  22.       character scaling will become a later article in this series.
  23.  
  24.            DEFINITIONS.   This  article  makes  use of  some terminology
  25.       which may be unfamiliar if you have not  used  digital  typefaces.
  26.       A mono-spaced font is one in  which  each  character  occupies  an
  27.       identically wide space on the screen.   A  proportional  font  has
  28.       characters which occupy different widths.   For  instance, an  'l'
  29.       would probably be narrower than a 'w'.
  30.  
  31.            Text may be "justified" right,  left,  or center.  This means
  32.       that  the right character,  left character,  or center position of
  33.       the  text  string is constrained to a given location.   In  common
  34.       usage,  a  page  of text is "ragged right" if its lines  are  left
  35.       justified only.   The text page is "fully justified",  "justified"
  36.       or  (ambiguously)  "right justified" if BOTH the  left  and  right
  37.       characters are contrained to fixed columns.  Full justification is
  38.       produced  by  inserting extra blank characters in the  case  of  a
  39.       mono-spaced font,  or by adding extra pixel columns in the case of
  40.       proportional output.
  41.  
  42.            A  text character (in a monospaced font) is written inside  a
  43.       standard sized cell or box.  Vertically, the cell extends from the
  44.       "top  line" down to the "bottom line".   If there are one or  more
  45.       blank  lines at the top or bottom,  they are called "leading"  and
  46.       are  used  to separate lines of text.   The characters  themselves
  47.       always  fall between the "ascent line",  which is the highest line
  48.       reached by characters such as 'd' and 'l', and the "descent line",
  49.       which  is the lowest line in characters like 'q' and  'g'.   Other
  50.       locations  of  interest are the "half line",  which is the top  of
  51.       characters  like  'a' or 'n',  and the "base line",  which is  the
  52.       bottom of characters which do not have descenders.
  53.  
  54.            Before  plunging into the Attribute Functions for  text,  you
  55.       should  note  that  the  writing  mode  (vswr_mode)  and  clipping
  56.       rectangle  (vs_clip) attributes discussed in the last column  (#9)
  57.       also  pertain  to  text.   Since much of the  discussion  of  text
  58.       optimization  will  center on these attributes,  you may  want  to
  59.       review them.
  60.  
  61.            TEXT ATTRIBUTES.   The writing color for graphics text is set
  62.       with the command:
  63.  
  64.                 vst_color(vdi_handle, color);
  65.  
  66.       Vdi_handle  is  always the handle returned from  graf_handle()  at
  67.       application startup.  Color is a word value between 0 and 15 which
  68.       designates  the  output  color index.   As discussed  in  previous
  69.       columns,  the  actual  color  which appears is  dependent  on  the
  70.       current  palette  settings.   In  applications such  as  word  and
  71.       outline  processors  it  is important that  characters  and  their
  72.       background  provide  good contrast to avoid eyestrain.   In  these
  73.       situations,  you  may  want to use the setPalette and/or  setColor
  74.       XBIOS  functions  to  force the palette to a  known  state  before
  75.       starting the application.
  76.  
  77.            You  can choose a variety of special output effects for  your
  78.       text with the call:
  79.  
  80.                 vst_effects(vdi_handle, effects);
  81.  
  82.       Effects is a single flag word,  with the bits having the following
  83.       significance:
  84.  
  85.                 0 - Thicken
  86.                 1 - Lighten
  87.                 2 - Skew
  88.                 3 - Underline
  89.                 4 - Outline
  90.                 5 - Shadow
  91.  
  92.       In each case,  turning the bit on selects the effect.   Otherwise,
  93.       the  effect  is  off.   Any  number of  multiple  effects  may  be
  94.       selected, but the result may not always be pleasing or legible.
  95.  
  96.            The  "thicken"  effect widens the character  strokes  by  one
  97.       pixel,   resulting  in  the  appearance  of  boldface  type.   The
  98.       "lighten" effect superimposes a half-tone dither on the character.
  99.       This mode is useful for indicating non-selectable text items,  but
  100.       is not legible enough for other purposes.
  101.  
  102.           The skew effect shifts the rows of the character to the right,
  103.       with  the greatest displacement at the top.   This results in  the
  104.       appearance of italic text.   You should be aware that the VDI does
  105.       not  compensate for this effect.   This means that a skewed italic
  106.       character which is immediately followed by a normal blank will  be
  107.       overstruck,  and  part of the top of the character will disappear.
  108.       Likewise,  a  skewed character written to the left of an  existing
  109.       normal  character will overstrike part of it.   There is a related
  110.       bug  in  the VDI clipping logic which may cause some  parts  of  a
  111.       skewed  character not to be redrawn if they fall at the edge of  a
  112.       clipping  rectangle,  even  though  they should  fall  within  the
  113.       region.
  114.  
  115.            The  outline  effect  produces output which is  a  one  pixel
  116.       "halo" around the normal character.  The shadow effect attempts to
  117.       create  a  "drop  shadow" to the side  of  the  character.   These
  118.       effects  should be used very sparingly with default  sized  fonts.
  119.       They often result in illegible output.
  120.  
  121.            When  graphics text is written,  a screen coordinate must  be
  122.       specified  for  the output.   The relationship of the text to  the
  123.       screen point is determined by the call:
  124.  
  125.                 vst_alignment(vdi_handle, hin, vin, &hout, &vout);
  126.  
  127.       Hin  and  vin are each words,  with values specifying the  desired
  128.       horizontal  and vertical alignment,  respectively.   Hout and vout
  129.       receive the actual values set by the VDI.  If they differ from the
  130.       requested values, an error has occurred.
  131.  
  132.            Hin may be set to zero for left justification, one for center
  133.       justification,  or  two  for right justification.   The coordinate
  134.       given when text is written becomes the "anchor point" as described
  135.       in the definitions above.  The default justification is left.
  136.  
  137.            Vin determines what reference line of the text is  positioned
  138.       at the output coordinate.  The selection values are:
  139.  
  140.                 0 - baseline (default)
  141.                 1 - half line
  142.                 2 - ascent line
  143.                 3 - bottom line
  144.                 4 - descent line
  145.                 5 - top line
  146.  
  147.            A  common combination of alignments is left (0) and top  line
  148.       (5).   This  mode guarantees that all text output will lie to  the
  149.       right and below the output coordinate.   This corresponds with the
  150.       AES object and GRECT coordinate systems.
  151.  
  152.            Finally, the call to do the actual output is:
  153.  
  154.                 v_gtext(vdi_handle, x, y, string);
  155.  
  156.       X  and y define the screen coordinate to be used as the  alignment
  157.       point.   String  is  a pointer to a null terminated string,  which
  158.       must  be total eighty characters or less,  exclusive of the  null.
  159.       This limit is imposed by the size of the intin[] array in the  VDI
  160.       binding.   Be  warned  that  it  is NOT checked  in  the  standard
  161.       binding!  Exceeding it may cause memory to be overwritten.
  162.  
  163.            One Inquire Function is useful with text output.  The call
  164.  
  165.                 vqt_attributes(vdi_handle, attrib);
  166.  
  167.       reads  back the current attribute settings into the 10 word  array
  168.       attrib[].   The  main  items  of interest  are  attrib[6]  through
  169.       attrib[9],  which contain the width and height of characters,  and
  170.       the  width and height of the character cell in the  current  font.
  171.       You  should  rely  on this function to  obtain  size  information,
  172.       rather  than using the output of the graf_handle()  function.   On
  173.       the ST, graf_handle() always returns sizes for the monochrome mode
  174.       system font, which will be incorrect in the color screen modes.
  175.  
  176.            Attrib[1] will contain the current graphics text color as set
  177.       by  vst_color().   Attrib[3]  and [4] contain the  horizontal  and
  178.       vertical alignment settings, respectively.  Attrib[5] contains the
  179.       current writing mode, as set by vswr_mode().
  180.  
  181.            OPTIMIZATION.  The most common complaint about using bit maps
  182.       for character output is lack of speed.  This section suggests ways
  183.       to  speed  things up.   By adopting all of these methods,  you can
  184.       realize an improvement of two to three times in speed.
  185.  
  186.            BYTE ALIGNMENT.   Since writing graphic text is essentially a
  187.       bit-blit operation,  characters which have "fringes",  that is, do
  188.       not  align  evenly with byte boundaries,  will suffer  performance
  189.       penalities.  The default system fonts in all resolutions of the ST
  190.       are  a  multiple of eight pixels wide,  so the problem reduces  to
  191.       assuring  that  each characters starts at a byte boundary  in  the
  192.       screen bit map.  This will be true if the horizontal pixel address
  193.       of the left edge of the character is evenly divisible by eight.
  194.  
  195.            Obviously,  byte  alignment  is easiest to enforce  when  the
  196.       horizontal justification is right or left.  Doing so with centered
  197.       text is possible, but requires adding padding blanks to odd length
  198.       strings.
  199.  
  200.            When  writing  text within windows,  it is helpful to  assure
  201.       that the edges of the window working area are byte aligned.  There
  202.       is  a section of code in the download which shows a technique  for
  203.       converting  a  user requested window position and/or size  to  its
  204.       working   dimensions,   byte-aligning  the  width  and  horizontal
  205.       position, and computing the adjusted external window coordinates.
  206.  
  207.            WRITING MODE.   The fastest text output mode is replace.  All
  208.       other modes require reading in the target raster area and  merging
  209.       it  with  the  new information.   You may find that you  must  use
  210.       transparent or reverse transparent mode,  for instance,  to use or
  211.       preserve an underlying background color other than white.  In this
  212.       case,  you  can  still  do  some optimization by  filling  in  the
  213.       background color for the entire string with a v_bar() call, rather
  214.       than doing it one character cell at a time.
  215.  
  216.            CLIPPING.    VDI  output  always  proceeds  faster  when  the
  217.       clipping rectangle is turned off, and text output is no exception.
  218.       Remember  that  you  may only do this if you are  drawing  into  a
  219.       dialog box,  or into the interior of a window which you know is on
  220.       top.   (You  can  use  the WM_TOPPED and  WM_NEWTOP  messages  for
  221.       keeping track of the top window, or use the WF_TOP wind_get() call
  222.       to  find the current top.)  In both of these cases,  you will know
  223.       the  width  of the drawing area,  and you can truncate the  output
  224.       string to fit exactly, rather than setting the clipping rectangle.
  225.       For this to work,  you must have used the byte alignment technique
  226.       to  assure  that the width of the writing area is  a  multiple  of
  227.       eight.
  228.  
  229.            BINDINGS.   The  normal binding for v_gtext() is inefficient.
  230.       It copies the string which you supply character-by-character  into
  231.       intin[] before it calls the VDI itself.  In many cases, it will be
  232.       more  efficient for your application to place characters  directly
  233.       into  intin[] and make the VDI trap call directly.   To give you a
  234.       start,  the  code  for  the standard v_gtext()  binding  has  been
  235.       included in the download.  When setting up intin[], be sure not to
  236.       load  more  than  80 characters,  or you will probably  crash  the
  237.       system!
  238.  
  239.            MOVING TEXT.  When performing text editing on the screen, you
  240.       should  avoid rewriting the string under edit  whenever  possible.
  241.       It is always more efficient to use the raster operations to move a
  242.       string  to  the right or left,  assuming that you have obeyed  the
  243.       byte  alignment rule.    If you are deleting characters,  blit the
  244.       unchanged part of the screen to the left,  and overstrike the last
  245.       character  in the string with a blank.   If inserting  characters,
  246.       blit  the  trailing  portion of the string  to  the  right  before
  247.       writing in the new character.
  248.  
  249.            THAT'S IT FOR NOW.   This concludes the two article series on
  250.       simple  VDI output.   Future columns may explore more complex  VDI
  251.       topics such as proportional text.  If there is something you would
  252.       like  to  see,  please  use the Online Feedback to  let  me  know!
  253.       Meanwhile,  the next column will give out the locations of some of
  254.       the  "hooks" and "trapdoors" built into the AES object  structure,
  255.       including  how  to set up user-defined AES drawing  objects.
  256.  
  257.  
  258.  
  259.  
  260. >>>>>>>>>>> Demonstration of byte alignment of window interior <<<<<<<<<<<
  261.  
  262. #define FEATURES    0x0fef    /* what border features are used   */
  263. WORD    msg[8];            /* message from evnt_multi       */
  264. GRECT    work_area;        /* defines working area        */
  265. WORD    w_hndl;            /* handle for window being changed */
  266.  
  267.     wind_calc(1, FEATURES, msg[4], msg[5], msg[6], msg[7], 
  268.         &work_area.g_x, &work_area.g_y, &work_area.g_w, 
  269.         &work_area.g_h);
  270.     work_area.g_x = align_x(work_area.g_x);
  271.     work_area.g_w = align_x(work_area.g_w);
  272.     wind_calc(0, FEATURES, work_area.g_x, work_area.g_y, 
  273.         work_area.g_w, work_area.g_h, &msg[4], &msg[5], 
  274.         &msg[6], &msg[7]); 
  275.     wind_set(w_hndl, WF_CXYWH, msg[4], msg[5], msg[6], msg[7]);
  276.  
  277.  
  278. >>>>>>>>>>>>>>>>>>>>> Subroutine for above <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  279.  
  280.     WORD
  281. align_x(x)        /* forces word alignment for column position    */
  282.     WORD    x;        /*   rounding to nearest word        */
  283.     {
  284.     return((x & 0xfff0) + ((x & 0x0008) ? 0x0010 : 0));
  285.     }    
  286.  
  287.  
  288. >>>>>>>>>>>>>>>>>>>>> Standard v_gtext binding <<<<<<<<<<<<<<<<<<<<<<<<<
  289.  
  290.     WORD
  291. v_gtext( handle, x, y, string)
  292.     WORD handle, x, y;
  293.     BYTE *string;
  294.     {
  295.     WORD i;
  296.     ptsin[0] = x;
  297.     ptsin[1] = y;
  298.     i = 0;
  299.     while (intin[i++] = *string++)    /* Copy characters to intin    */
  300.         ;            /* There is NO error checking! */
  301.     contrl[0] = 8;
  302.     contrl[1] = 1;
  303.     contrl[3] = --i;
  304.     contrl[6] = handle;
  305.     vdi();
  306.     }
  307.